home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of MacTutor - S…e Code for Volumes 1 to 5
/
The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin
/
Source Code
/
#49 (Oct 89)
/
SC #49.sit
/
XCMDs Source
< prev
Wrap
Text File
|
1989-09-12
|
5KB
|
246 lines
/**********************************/
/* File: FileCopy.c */
/* */
/* param0 = file reference num */
/* ( file is open ) */
/* ---------------------------- */
/* */
/* IN: */
/* params[0] = name of input */
/* params[1] = wdid of input */
/* params[2] = name of output */
/* params[3] = wdid of output */
/**********************************/
#include <MacTypes.h>
#include <OSUtil.h>
#include <MemoryMgr.h>
#include <FileMgr.h>
#include <ResourceMgr.h>
#include <pascal.h>
#include <string.h>
#include "HyperXCMD.h"
#include "HyperUtils.h"
pascal void main( paramPtr )
XCmdBlockPtr paramPtr;
/*****************************
* params[0] = name of input
* params[1] = wdid of input
* params[2] = name of output
* params[3] = wdid of output
*
*****************************/
{
OSErr err;
short inWD;
short outWD;
long temp;
Str31 errCode;
char inFile[256];
char outFile[256];
paramPtr->returnValue = 0L;
/*** (1) Get input parameters ***/
HLock( paramPtr->params[0] );
ZeroToPas( paramPtr, *(paramPtr->params[0]), &inFile );
HUnlock( paramPtr->params[0] );
inWD = (short)paramtoNum( paramPtr, 1 );
HLock( paramPtr->params[2] );
ZeroToPas( paramPtr, *(paramPtr->params[2]), &outFile );
HUnlock( paramPtr->params[2] );
outWD = (short)paramtoNum( paramPtr, 3 );
temp = (long)CopyFile( inFile, inWD, outFile, outWD );
/*** Flush the output volume ***/
err = FlushVol( 0L, 0 );
NumToStr( paramPtr, temp, &errCode );
paramPtr->returnValue = PasToZero( paramPtr, &errCode );
}
LISTING 1: CopyFile XCMD.
OSErr CopyFork( inref, outref, siz )
short inref;
short outref;
long siz;
/*****************************
* Given that the caller has opened
* a fork and passed you the names of
* the input, copy the number of bytes
* from the input fork to the output
* fork.
*
* The input mark should be set to
* start of fork.
*
* We use a "semi-smart" algorithm
* to do the copy. If the entire
* fork can be copied, we try doing
* that, otherwise, we keep dividing
* the size by two until we get enough
* room to read some data in.
*
******************************/
{
OSErr rd_err = noErr;
OSErr wrt_err = noErr;
long rd_len; /*** actual bytes read ***/
Ptr inbuf;
/*** make sure that the size is even ***/
if( siz % 2 )
++siz;
if( siz > 0 ){
do{
inbuf = NewPtr( siz );
if( !inbuf )
siz = ( siz >> 1 );
}while( !inbuf );
/*** inbuf is the buffer that we ***/
/*** read the data into. If not ***/
/*** allocated, don't attempt to do ***/
/*** the read ***/
if( inbuf ){
do{
rd_len = siz;
rd_err = FSRead( inref, &rd_len, inbuf );
wrt_err= FSWrite( outref, &rd_len, inbuf );
}while( !rd_err && !wrt_err );
DisposPtr( inbuf );
}
}
return( wrt_err );
}
OSErr CopyFile( inFile, inWD, outFile, outWD )
char *inFile;
short inWD;
char *outFile;
short outWD;
/*****************************
* (1) Determine the size of the input
* file.
*
* (2) Attempt to allocate that
* much space for the output file.
*
* (3) If allocation successful,
* create the output file.
*
* (4) Once the file is created,
* copy the data fork, the resource
* fork and the finder information
* from the input file.
*
* The file will be called "copy of..."
* Each time we create the file, first
* see if that name exists, if so, keep
* sticking "copy of" onto the name.
******************************/
{
OSErr err;
OSErr err2;
short inref;
short outref;
long data_eof = 0L;
long rsrc_eof = 0L;
FInfo fndrinfo;
/*** (2) Determine how big the input file is ***/
if( (err = FSOpen( inFile, inWD, &inref )) == noErr){
err = GetEOF( inref, &data_eof );
err = FSClose( inref );
}
if( (err = OpenRF( inFile, inWD, &inref )) == noErr ){
err = GetEOF( inref, &rsrc_eof );
err = FSClose( inref );
}
/*** (2) Create output file and allocate space***/
if( ( err = GetFInfo( inFile, inWD, &fndrinfo ) ) != noErr )
return( err );
if( ( err = Create( outFile, inWD, fndrinfo.fdCreator, fndrinfo.fdType )) != noErr )
return( err );
/*** (3) Try to allocate enough space for both***/
/*** forks. Note that if we get enough space. ***/
if( (err = FSOpen( outFile, outWD, &outref )) != noErr)
return( err );
if( (err = SetEOF( outref, data_eof )) != noErr ){
err2 = FSClose( outref );
err2 = FSDelete( outFile, outWD );
return( err );
}
err2 = FSClose( outref );
err = OpenRF( outFile, outWD, &outref );
if( (err = SetEOF( outref, rsrc_eof )) != noErr ){
err2 = FSClose( outref );
err2 = FSDelete( outFile, outWD );
return( err );
}
err2 = FSClose( outref );
/*** (4) Copy the Data fork ***/
err = FSOpen( inFile, inWD, &inref );
if( !err ){
err2 = SetFPos( inref, fsFromStart, 0L );
err = CopyFork( inref, outref, data_eof );
err2 = FSClose( inref );
err2 = FSClose( outref );
}
if( err ){
err2 = FSDelete( outFile, outWD );
return( err );
}
/*** (5) Now copy the resource fork ***/
err = OpenRF( inFile, inWD, &inref );
if( !err ){
err2 = SetFPos( inref, fsFromStart, 0L );
err = OpenRF( outFile, outWD, &outref );
err = CopyFork( inref, outref, rsrc_eof );
err2 = FSClose( inref );
err2 = FSClose( outref );
}
if( err ){
err2 = FSDelete( outFile, outWD );
return( err );
}
return( noErr );
}
LISTING 2: CopyFile and CopyFork Functions.